using MediatR;
using Microsoft.AspNetCore.Mvc;
using NPOI.XSSF.UserModel;
using RBAC.Domain.Dto.Output;
using RBAC.Domain.SalesManage;
using RBAC.ErrorCode;
using RBAC.Read.Api.Application.Command.ERP.SalesManagement;
using RBAC.Read.Api.Application.Command.ERP.SalesManagement.Billing;
using RBAC.Read.Api.Application.Command.ERP.SalesManagement.H;
using RBAC.Read.Api.Application.Command.ERP.SalesManagement.Return;
using RBAC.Read.Api.Application.Dto.ERP;
using RBAC.Read.Api.Application.Dto.ERP.SalesManagement.H;
using RBAC.Read.Api.Utils;
using System.Reflection;

namespace RBAC.Read.Api.Controllers.ERP
{
    /// <summary>
    /// 销售管理控制器 
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class SalesManagementController : ControllerBase
    {
        private readonly IMediator mediator;
        private readonly ILogger<SalesManagementController> _logger;

        public SalesManagementController(IMediator mediator, ILogger<SalesManagementController> logger)
        {
            this.mediator = mediator;
            this._logger = logger;
        }


        #region 销售订单

        /// <summary>
        /// 获取销售订单分页列表
        /// </summary>
        /// <param name="request">分页查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>销售订单分页结果</returns>
        [HttpGet]
        public Task<APIPaging<SalesOrderDto>> GetSalesOrderPage([FromQuery] SalesOrderPageCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        #region 兼容旧版本

        /*
                 /// <summary>
        /// 获取销售订单分页列表（兼容旧接口）
        /// </summary>
        /// <param name="request">分页查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>销售订单分页结果</returns>
        [HttpGet]
        public Task<APIPaging<SalesOrderDto>> GetSalesOrderPageList([FromQuery] SalesOrderPageCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

                /// <summary>
        /// 根据ID获取销售订单详情（兼容旧接口）
        /// </summary>
        /// <param name="id">销售订单ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>销售订单详情结果</returns>
        [HttpGet("detail/{id}")]
        public Task<APIResult<SalesOrderDetailDto>> GetSalesOrderDetail(long id, CancellationToken cancellationToken)
        {
            var command = new SalesOrderGetDetailByIdCommand { Id = id };
            return mediator.Send(command, cancellationToken);
        }
         */

        #endregion


        /// <summary>
        /// 根据ID获取销售订单详情
        /// </summary>
        /// <param name="id">销售订单ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>销售订单详情结果</returns>
        [HttpGet("{id}")]
        public Task<APIResult<SalesOrderDetailDto>> GetSalesOrderDetailById(long id, CancellationToken cancellationToken)
        {
            var command = new SalesOrderGetDetailByIdCommand { Id = id };
            return mediator.Send(command, cancellationToken);
        }
        #endregion


        /// <summary>
        /// 无条件查询销售订单明细列表（仅返回未删除的明细）
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>销售订单明细项列表</returns>
        [HttpGet("GetSalesOrderDetailItems")]
        public Task<APIResult<List<SalesOrderDetailItemDto>>> GetSalesOrderDetailItems(CancellationToken cancellationToken)
        {
            var cmd = new GetSalesOrderDetailItemsCommand();
            return mediator.Send(cmd, cancellationToken);
        }

        /// <summary>
        /// 获取销售订单列表（GET方式） 
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="salesOrderNumber">销售订单号</param>
        /// <param name="materialCode">物料编码</param>
        /// <param name="materialName">物料名称</param>
        /// <returns>销售订单列表</returns>
        [HttpGet("GetSalesOrderList")]
        public async Task<APIResult<GetSalesOrderListDto>> GetSalesOrderList(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 10,
            [FromQuery] string? salesOrderNumber = null,
            [FromQuery] string? materialCode = null,
            [FromQuery] string? materialName = null)
        {
            var command = new GetSalesOrderListCommand
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
                SalesOrderNumber = salesOrderNumber,
                MaterialCode = materialCode,
                MaterialName = materialName
            };

            return await mediator.Send(command);
        }

        /// <summary>
        /// 销售订单计划查询（与截图列一致）
        /// </summary>
        /// <param name="request">查询参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>查询结果</returns>
        [HttpGet("GetSalesOrderPlanList")]
        public Task<APIResult<GetSalesOrderPlanListDto>> GetSalesOrderPlanList([FromQuery] GetSalesOrderPlanListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 销售订单计划查询（图2条件：销售订单号/单据编码/客户名称/销售员/物料名称/状态/开始结束日期）
        /// </summary>
        /// <param name="request">筛选与分页参数（图2）</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分页结果</returns>
        [HttpGet("GetSalesOrderPlanListByBill")]
        public Task<APIResult<GetSalesOrderPlanListByBillDto>> GetSalesOrderPlanListByBill(
            [FromQuery] GetSalesOrderPlanListByBillCommand request,
            CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 导出：销售订单计划查询结果（根据筛选条件，可无条件）
        /// </summary>
        /// <param name="request">筛选条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel 文件</returns>
        [HttpGet("ExportSalesOrderPlanList")]
        public async Task<IActionResult> ExportSalesOrderPlanList([FromQuery] ExportSalesOrderPlanListCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始导出销售订单计划结果，筛选条件: {@Request}", request);

                var excelBytes = await mediator.Send(request, cancellationToken);

                if (excelBytes == null || excelBytes.Length == 0)
                {
                    _logger.LogWarning("导出数据为空");
                    return BadRequest("导出数据为空，请检查筛选条件");
                }

                var (safeFileName, displayFileName) = FileNameHelper.GenerateSalesOrderFileName();
                var contentDisposition = FileNameHelper.GenerateContentDisposition(safeFileName, displayFileName);
                Response.Headers["Content-Disposition"] = contentDisposition;
                Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
                Response.Headers["Pragma"] = "no-cache";
                Response.Headers["Expires"] = "0";
                Response.Headers["Content-Length"] = excelBytes.Length.ToString();

                const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                _logger.LogInformation("导出完成，文件大小: {Size} bytes", excelBytes.Length);
                return File(excelBytes, contentType, safeFileName);
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("导出操作被取消");
                return StatusCode(499, "导出操作被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出销售订单计划失败: {Message}", ex.Message);
                return StatusCode(500, $"导出失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 销售订单综合查询（支持条件/无条件，GET）
        /// </summary>
        /// <param name="request">筛选与分页参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>综合查询结果</returns>
        [HttpGet("GetSalesOrderSummary")]
        public Task<APIResult<GetSalesOrderSummaryDto>> GetSalesOrderSummary(
            [FromQuery] GetSalesOrderSummaryCommand request,
            CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 销售订单 KPI（最近7/30/365天，按日或按月分组）
        /// </summary>
        /// <param name="request">Days=7/30/365, GroupBy=day/month</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>分组后的订单数与销售额</returns>
        [HttpGet("GetSalesOrderKpi")]
        public Task<APIResult<GetSalesOrderKpiDto>> GetSalesOrderKpi(
            [FromQuery] GetSalesOrderKpiCommand request,
            CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 客户模糊查询（返回Id与名称）
        /// </summary>
        /// <param name="request">关键词与Top数量</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>客户选项列表</returns>
        [HttpGet("SearchCustomer")]
        public Task<APIResult<List<CustomerOptionDto>>> SearchCustomer(
            [FromQuery] SearchCustomerCommand request,
            CancellationToken cancellationToken)
        {
            _logger.LogInformation("客户模糊查询，Keyword={Keyword}, Top={Top}", request.Keyword, request.Top);
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 导出：销售订单综合查询结果（根据筛选条件，可无条件）
        /// </summary>
        /// <param name="request">筛选条件（与 GetSalesOrderSummary 一致）</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel文件</returns>
        [HttpGet("ExportSalesOrderSummary")]
        public async Task<IActionResult> ExportSalesOrderSummary([FromQuery] ExportSalesOrderSummaryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始导出销售订单综合查询结果，筛选条件: {@Request}", request);

                var excelBytes = await mediator.Send(request, cancellationToken);

                if (excelBytes == null || excelBytes.Length == 0)
                {
                    _logger.LogWarning("导出数据为空");
                    return BadRequest("导出数据为空，请检查筛选条件");
                }

                var (safeFileName, displayFileName) = FileNameHelper.GenerateSalesOrderFileName();
                var contentDisposition = FileNameHelper.GenerateContentDisposition(safeFileName, displayFileName);
                Response.Headers["Content-Disposition"] = contentDisposition;
                Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
                Response.Headers["Pragma"] = "no-cache";
                Response.Headers["Expires"] = "0";
                Response.Headers["Content-Length"] = excelBytes.Length.ToString();

                const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                _logger.LogInformation("导出完成，文件大小: {Size} bytes", excelBytes.Length);

                return File(excelBytes, contentType, safeFileName);
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("导出操作被取消");
                return StatusCode(499, "导出操作被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出销售订单综合查询失败: {Message}", ex.Message);
                return StatusCode(500, $"导出失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 导出销售订单明细表（无条件，返回未删除的明细）
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel 文件</returns>
        [HttpGet("ExportSalesOrderDetailItems")]
        public async Task<IActionResult> ExportSalesOrderDetailItems(CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始导出销售订单明细表（无条件）");

                var cmd = new GetSalesOrderDetailItemsCommand();
                var result = await mediator.Send(cmd, cancellationToken);

                if (result == null || result.Code != APIEnums.Success || result.Data == null || result.Data.Count == 0)
                {
                    _logger.LogWarning("无可导出的销售订单明细数据");
                    return BadRequest("导出数据为空");
                }

                var workbook = new XSSFWorkbook();
                var sheet = workbook.CreateSheet("销售订单明细");

                var headerStyle = workbook.CreateCellStyle();
                var headerFont = workbook.CreateFont();
                headerFont.IsBold = true;
                headerStyle.SetFont(headerFont);

                var headers = new[]
                {
                    "序号","物料编码","物料名称","型号规格","主计量",
                    "数量","单价","金额","备注信息","创建时间","创建人"
                };

                var headerRow = sheet.CreateRow(0);
                for (int i = 0; i < headers.Length; i++)
                {
                    var cell = headerRow.CreateCell(i);
                    cell.SetCellValue(headers[i]);
                    cell.CellStyle = headerStyle;
                }

                int rowIndex = 1;
                foreach (var d in result.Data)
                {
                    var row = sheet.CreateRow(rowIndex++);
                    row.CreateCell(0).SetCellValue(d.SerialNo);
                    row.CreateCell(1).SetCellValue(d.MaterCode ?? "");
                    row.CreateCell(2).SetCellValue(d.MaterName ?? "");
                    row.CreateCell(3).SetCellValue(d.ModelSpec ?? "");
                    row.CreateCell(4).SetCellValue(d.Unit ?? "");
                    row.CreateCell(5).SetCellValue(d.Num.HasValue ? d.Num.Value.ToString() : "0");
                    row.CreateCell(6).SetCellValue(d.Price.HasValue ? d.Price.Value.ToString("F4") : "0.0000");
                    row.CreateCell(7).SetCellValue(d.Amount.HasValue ? d.Amount.Value.ToString("F4") : "0.0000");
                    row.CreateCell(8).SetCellValue(d.Remark ?? "");
                    row.CreateCell(9).SetCellValue(d.CreateTime == default ? "" : d.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                    row.CreateCell(10).SetCellValue(d.CreateUser ?? "");
                }

                for (int i = 0; i < headers.Length; i++)
                {
                    sheet.AutoSizeColumn(i);
                }

                using var ms = new MemoryStream();
                workbook.Write(ms);
                var bytes = ms.ToArray();

                var (safeFileName, displayFileName) = FileNameHelper.GenerateSalesOrderFileName();
                var contentDisposition = FileNameHelper.GenerateContentDisposition(safeFileName, displayFileName);
                Response.Headers["Content-Disposition"] = contentDisposition;
                Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
                Response.Headers["Pragma"] = "no-cache";
                Response.Headers["Expires"] = "0";
                Response.Headers["Content-Length"] = bytes.Length.ToString();

                const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                _logger.LogInformation("导出销售订单明细完成，记录数：{Count}，文件大小：{Size} bytes", result.Data.Count, bytes.Length);
                return File(bytes, contentType, safeFileName);
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("导出销售订单明细操作被取消");
                return StatusCode(499, "导出操作被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出销售订单明细失败: {Message}", ex.Message);
                return StatusCode(500, $"导出失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取用户选项列表（仅返回 Id、Name）
        /// </summary>
        /// <param name="request">关键词与Top数量</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>用户选项列表</returns>
        [HttpGet("GetUserList")]
        public Task<APIResult<List<UserOptionDto>>> GetUserList([FromQuery] GetUserListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        #region 物料

        /// <summary>
        /// 物料分类树形展示
        /// </summary>
        [HttpGet]
        public Task<APIResult<List<MaterTypeTreeDto>>> GetMaterTypeTree(CancellationToken cancellationToken)
        {
            var command = new GetMaterTypeTreeCommand();
            return mediator.Send(command, cancellationToken);
        }

        /// <summary>
        /// 物料分页列表
        /// </summary>
        [HttpGet]
        public Task<APIPaging<MaterListDto>> GetMaterPage([FromQuery] GetMaterPageCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        #endregion

        #region 发货通知单

        /// <summary>
        /// 获取发货通知单列表
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>发货通知单列表结果</returns>
        [HttpGet]
        public Task<APIResult<GetDeliveryNoticeListDto>> GetDeliveryNoticeList([FromQuery] GetDeliveryNoticeListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 获取发货通知单明细列表
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>发货通知单明细列表结果</returns>
        [HttpGet]
        public Task<APIResult<GetDeliveryNoticeItemListDto>> GetDeliveryNoticeItemList([FromQuery] GetDeliveryNoticeItemListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 发货通知单所有数据（联查 Delivery_notice、SalesOrder、Delivery_notice_item、SalesOrderDetail、Mater、MaterType）
        /// 支持无条件查询与条件查询
        /// </summary>
        /// <param name="request">筛选条件（单据编码/销售订单号/客户名称/销售员/物料名称/状态/业务类型/开始结束日期）</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>联查结果列表</returns>
        [HttpGet("GetDeliveryNoticeAllData")]
        public Task<APIResult<List<DeliveryNoticeAllDataDto>>> GetDeliveryNoticeAllData(
            [FromQuery] GetDeliveryNoticeAllDataCommand request,
            CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 导出：发货通知单所有数据（联查结果，支持同查询接口的筛选条件）
        /// </summary>
        /// <param name="request">与 GetDeliveryNoticeAllData 相同的筛选参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel 文件</returns>
        [HttpGet("ExportDeliveryNoticeAllData")]
        public async Task<IActionResult> ExportDeliveryNoticeAllData(
            [FromQuery] GetDeliveryNoticeAllDataCommand request,
            CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始导出发货通知单所有数据，筛选条件: {@Request}", request);

                var result = await mediator.Send(request, cancellationToken);
                if (result == null || result.Code != APIEnums.Success || result.Data == null || result.Data.Count == 0)
                {
                    _logger.LogWarning("导出数据为空");
                    return BadRequest("导出数据为空，请检查筛选条件");
                }

                // 通过反射动态生成列，避免依赖具体字段，保证不影响其他方法
                var dtoType = typeof(DeliveryNoticeAllDataDto);
                var props = dtoType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                var workbook = new XSSFWorkbook();
                var sheet = workbook.CreateSheet("发货通知单(联查)");

                var headerStyle = workbook.CreateCellStyle();
                var headerFont = workbook.CreateFont();
                headerFont.IsBold = true;
                headerStyle.SetFont(headerFont);

                // 表头
                var headerRow = sheet.CreateRow(0);
                for (int i = 0; i < props.Length; i++)
                {
                    var cell = headerRow.CreateCell(i);
                    cell.SetCellValue(props[i].Name);
                    cell.CellStyle = headerStyle;
                }

                // 数据
                int rowIndex = 1;
                foreach (var item in result.Data)
                {
                    var row = sheet.CreateRow(rowIndex++);
                    for (int i = 0; i < props.Length; i++)
                    {
                        var val = props[i].GetValue(item, null);
                        row.CreateCell(i).SetCellValue(val?.ToString() ?? string.Empty);
                    }
                }

                for (int i = 0; i < props.Length; i++)
                {
                    sheet.AutoSizeColumn(i);
                }

                using var ms = new MemoryStream();
                workbook.Write(ms);
                var bytes = ms.ToArray();

                var (safeFileName, displayFileName) = FileNameHelper.GenerateDeliveryNoticeFileName();
                var contentDisposition = FileNameHelper.GenerateContentDisposition(safeFileName, displayFileName);
                Response.Headers["Content-Disposition"] = contentDisposition;
                Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
                Response.Headers["Pragma"] = "no-cache";
                Response.Headers["Expires"] = "0";
                Response.Headers["Content-Length"] = bytes.Length.ToString();

                const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                _logger.LogInformation("导出发货通知单所有数据完成，记录数：{Count}，文件大小：{Size} bytes", result.Data.Count, bytes.Length);
                return File(bytes, contentType, safeFileName);
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("导出操作被取消");
                return StatusCode(499, "导出操作被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出发货通知单所有数据失败: {Message}", ex.Message);
                return StatusCode(500, $"导出失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 导出发货通知单（根据筛选条件）
        /// </summary>
        /// <param name="request">导出请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel文件</returns>
        [HttpGet("ExportDeliveryNotice")]
        public async Task<IActionResult> ExportDeliveryNotice([FromQuery] ExportDeliveryNoticeCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始导出发货通知单，筛选条件: {@Request}", request);

                var excelData = await mediator.Send(request, cancellationToken);

                if (excelData == null || excelData.Length == 0)
                {
                    _logger.LogWarning("导出的Excel数据为空");
                    return BadRequest("导出数据为空，请检查筛选条件");
                }

                _logger.LogInformation("Excel数据生成成功，文件大小: {FileSize} bytes", excelData.Length);

                // 使用文件名帮助类生成安全的文件名
                var (safeFileName, displayFileName) = FileNameHelper.GenerateDeliveryNoticeFileName();

                // 设置响应头，使用RFC 5987标准处理文件名编码
                var contentDisposition = FileNameHelper.GenerateContentDisposition(safeFileName, displayFileName);
                Response.Headers["Content-Disposition"] = contentDisposition;
                Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
                Response.Headers["Pragma"] = "no-cache";
                Response.Headers["Expires"] = "0";
                Response.Headers["Content-Length"] = excelData.Length.ToString();

                // 设置响应类型
                var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

                _logger.LogInformation("开始返回Excel文件，安全文件名: {SafeFileName}, 显示文件名: {DisplayFileName}, 大小: {FileSize} bytes",
                    safeFileName, displayFileName, excelData.Length);

                return File(excelData, contentType, safeFileName);
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("导出发货通知单操作被取消");
                return StatusCode(499, "导出操作被取消");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出发货通知单失败: {Message}", ex.Message);
                return StatusCode(500, $"导出失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 测试导出发货通知单功能
        /// </summary>
        /// <returns>测试结果</returns>
        [HttpGet("TestExport")]
        public IActionResult TestExport()
        {
            try
            {
                _logger.LogInformation("测试导出发货通知单功能");

                // 创建一个简单的测试数据
                var testData = new
                {
                    Message = "导出发货通知单功能测试成功",
                    Timestamp = DateTime.Now,
                    Status = "OK",
                    Features = new[]
                    {
                        "条件筛选导出",
                        "动态SQL构建",
                        "参数化查询",
                        "Excel文件生成",
                        "文件下载支持"
                    }
                };

                return Ok(testData);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "测试导出发货通知单功能失败");
                return StatusCode(500, $"测试失败: {ex.Message}");
            }
        }



        /// <summary>
        /// 检查发货通知单数据（用于调试）
        /// </summary>
        /// <returns>数据检查结果</returns>
        [HttpGet("CheckData")]
        public async Task<IActionResult> CheckData()
        {
            try
            {
                _logger.LogInformation("开始检查发货通知单数据");

                // 创建一个简单的查询来检查数据
                var request = new ExportDeliveryNoticeCommand();
                var excelData = await mediator.Send(request, CancellationToken.None);

                if (excelData == null || excelData.Length == 0)
                {
                    return Ok(new { Message = "没有数据可导出", DataSize = 0 });
                }

                // 返回数据信息
                var result = new
                {
                    Message = "数据检查完成",
                    DataSize = excelData.Length,
                    FileSizeKB = Math.Round(excelData.Length / 1024.0, 2),
                    Timestamp = DateTime.Now,
                    Status = "Success"
                };

                _logger.LogInformation("数据检查完成: {Result}", result);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据检查失败: {Message}", ex.Message);
                return StatusCode(500, new { Message = $"数据检查失败: {ex.Message}", Status = "Error" });
            }
        }

        [HttpGet("TestRawData")]
        public async Task<IActionResult> TestRawData()
        {
            try
            {
                _logger.LogInformation("开始测试原始数据查询");

                // 使用mediator来调用查询
                var request = new ExportDeliveryNoticeCommand();
                var excelData = await mediator.Send(request, CancellationToken.None);

                var result = new
                {
                    Message = "原始数据查询完成",
                    FileSize = excelData?.Length ?? 0,
                    Timestamp = DateTime.Now
                };

                _logger.LogInformation("原始数据查询完成: {Result}", result);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "原始数据查询失败: {Message}", ex.Message);
                return StatusCode(500, new { Message = $"原始数据查询失败: {ex.Message}", Status = "Error" });
            }
        }

        
        #endregion

        #region 开票通知单

        /// <summary>
        /// 获取开票通知单列表（单据模式）
        /// </summary>
        /// <param name="request">查询参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>开票通知单列表</returns>
        [HttpGet("GetBillingNoticeList")]
        public Task<APIResult<GetBillingNoticeListDto>> GetBillingNoticeList([FromQuery] GetBillingNoticeListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 获取开票明细列表（明细模式）
        /// </summary>
        /// <param name="request">查询参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>开票明细列表</returns>
        [HttpGet("GetBillingDetailList")]
        public Task<APIResult<GetBillingDetailListDto>> GetBillingDetailList([FromQuery] GetBillingDetailListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        #endregion

        #region 客户档案
        /// <summary>
        /// 获取客户分页列表
        /// </summary>
        /// <param name="request">分页与筛选请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>客户分页结果</returns>
        [HttpGet("GetCustomerList")]
        public Task<APIResult<APIPaging<Customer>>> GetCustomerList([FromQuery] GetCustomerCommands request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 根据Id获取客户（反填）
        /// </summary>
        /// <param name="id">客户Id</param>
        /// <returns>客户实体</returns>
        [HttpGet("Customer/{id}")]
        public async Task<APIResult<Customer>> GetCustomerById([FromRoute] int id)
        {
            var cmd = new GetCustomerByIdCommands { CustomerId = id };
            return await mediator.Send(cmd);
        }

        /// <summary>
        /// 导出客户列表到Excel
        /// </summary>
        /// <param name="request">导出参数</param>
        /// <returns>Excel文件</returns>
        [HttpGet("ExportCustomerLists")]
        public async Task<IActionResult> ExportCustomerList([FromQuery] GetExportInfoCommands request)
        {
            var result = await mediator.Send(request);

            if (result.Code == APIEnums.Success && result.Data.Length > 0)
            {
                var ts = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                var fileName = $"客户列表_{ts}.xlsx";
                const string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                return File(result.Data, contentType, fileName);
            }
            else
            {
                return BadRequest(result);
            }
        }

        /// <summary>
        /// 打印客户列表（不分页，供前端打印）
        /// </summary>
        /// <param name="request">可选的客户名称/电话模糊过滤</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>客户列表</returns>
        [HttpGet("PrintCustomerList")]
        public Task<APIResult<List<Customer>>> PrintCustomerList([FromQuery] GetPrintCustomerCommands request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 根据单据编号获取开票通知单详情
        /// </summary>
        /// <param name="billNumber">单据编号</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>开票通知单详情</returns>
        [HttpGet("GetBillingNoticeDetail/{billNumber}")]
        public Task<APIResult<BillingNoticeDetailDto>> GetBillingNoticeDetail([FromRoute] string billNumber, CancellationToken cancellationToken)
        {
            var command = new GetBillingNoticeDetailCommand { BillNumber = billNumber };
            return mediator.Send(command, cancellationToken);
        }

        #endregion

        #region 退货通知单

        /// <summary>
        /// 获取退货通知单列表
        /// </summary>
        /// <param name="request">查询参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>退货通知单列表</returns>
        [HttpGet("GetReturnNoticeList")]
        public Task<APIResult<GetReturnNoticeListDto>> GetReturnNoticeList([FromQuery] GetReturnNoticeListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        /// <summary>
        /// 获取退货通知单明细列表
        /// </summary>
        /// <param name="request">查询参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>退货通知单明细列表</returns>
        [HttpGet("return-notices/details")]
        public Task<APIResult<GetReturnNoticeDetailListDto>> GetReturnNoticeDetailList([FromQuery] GetReturnNoticeDetailListCommand request, CancellationToken cancellationToken)
        {
            return mediator.Send(request, cancellationToken);
        }

        #endregion
    }
}